package org.hackystat.projectbrowser.page.settrigger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.hackystat.ambientdevice.server.jaxb.Trigger;
import org.hackystat.projectbrowser.page.setaction.SetActionPage;

/**
 * The form that gets the data fro trigger options.
 * 
 * @author Edward Kim
 * 
 */
public class SetTriggerForm extends Form {
  /** Support serialization. */
  private static final long serialVersionUID = 1L;

  private final TriggerModel triggerModel;
  private final PageParameters param;
  private final String projectName;

  private static final String TYPE_TOKEN = "type";
  private static final String SDT_TOKEN = "sdt";
  private static final String ID_TOKEN = "id";
  private static final String MINVALUE_TOKEN = "minValue";
  private static final String MAXVALUE_TOKEN = "maxValue";
  private static final String PROPERTY_TOKEN = "property";
  private static final String VALUE_TOKEN = "value";

  /** Strings containing what user has selected within dropdown menus. */
  private String selectedTriggerType = "";
  private String selectedTriggerSdt = "";
  private String selectedTriggerProperty = "";
  private String selectedTriggerValue = "";
  private String selectedTriggerMinValue = "";
  private String selectedTriggerMaxValue = "";

  /** Maps to put in what will show in drop down menus */
  private Map<String, ArrayList<String>> triggerMap = new HashMap<String, ArrayList<String>>();
  private Map<String, ArrayList<String>> sdtMap = new HashMap<String, ArrayList<String>>();
  private Map<String, ArrayList<String>> propertyMap = new HashMap<String, ArrayList<String>>();
  private Map<String, ArrayList<String>> valueMap = new HashMap<String, ArrayList<String>>();

  /**
   * Constructor
   * 
   * @param id Passed to super (not really needed).
   * @param model The current model.
   * @param param The page parameters.
   */
  @SuppressWarnings("serial")
  public SetTriggerForm(String id, TriggerModel model, PageParameters param) {
    super(id);

    this.triggerModel = model;
    this.param = param;
    this.projectName = param.getStringValue("projectName").toString();

    sdtMap.put("SensorData", TriggerModel.getChoices("SensorData"));
    sdtMap.put("Coverage", TriggerModel.getChoices("Coverage"));

    propertyMap.put("Build", TriggerModel.getChoices("Build"));
    propertyMap.put("UnitTest", TriggerModel.getChoices("UnitTest"));
    // propertyMap.put("Commit", TriggerModel.getChoices("Commit"));
    propertyMap.put("Not Applicable", TriggerModel.getChoices("Not Applicable"));

    valueMap.put("Compare", TriggerModel.getChoices("Compare"));
    valueMap.put("Target", TriggerModel.getChoices("Target"));
    valueMap.put("Result", TriggerModel.getChoices("Result"));
    valueMap.put("Tool", TriggerModel.getChoices("Tool"));

    IModel sdtModel = new AbstractReadOnlyModel() {
      @SuppressWarnings("unchecked")
      public Object getObject() {
        if ((List<String>) sdtMap.get(selectedTriggerType) == null) {
          return Collections.emptyList();
        }
        else {
          return (List<String>) sdtMap.get(selectedTriggerType);
        }
      }
    };

    IModel propertyModel = new AbstractReadOnlyModel() {
      @SuppressWarnings("unchecked")
      public Object getObject() {
        if ((List<String>) propertyMap.get(selectedTriggerSdt) == null) {
          return Collections.emptyList();
        }
        else {
          return (List<String>) propertyMap.get(selectedTriggerSdt);
        }
      }
    };

    IModel valueModel = new AbstractReadOnlyModel() {
      @SuppressWarnings("unchecked")
      public Object getObject() {
        if ((List<String>) valueMap.get(selectedTriggerProperty) == null) {
          return Collections.emptyList();
        }
        else {
          return (List<String>) valueMap.get(selectedTriggerProperty);

        }
      }
    };

    System.out.println("Dropdown choices");
    final DropDownChoice typeChoices = new DropDownChoice("type", new PropertyModel(this,
        "selectedTriggerType"), new Model(TriggerModel.getChoices("type")));
    final DropDownChoice sdtChoices = new DropDownChoice("sdt", new PropertyModel(this,
        "selectedTriggerSdt"), sdtModel);
    final DropDownChoice propertyChoices = new DropDownChoice("property", new PropertyModel(this,
        "selectedTriggerProperty"), propertyModel);
    final DropDownChoice valueChoices = new DropDownChoice("valueModel", new PropertyModel(this,
        "selectedTriggerValue"), valueModel);

    typeChoices.setOutputMarkupId(true);
    sdtChoices.setOutputMarkupId(true);
    propertyChoices.setOutputMarkupId(true);
    valueChoices.setOutputMarkupId(true);

    typeChoices.setRequired(true);
    sdtChoices.setRequired(true);
    propertyChoices.setRequired(true);
    valueChoices.setRequired(true);
    add(typeChoices);
    add(sdtChoices);
    add(propertyChoices);
    add(valueChoices);

    typeChoices.add(new AjaxFormComponentUpdatingBehavior("onchange") {
      /**
       * 
       */
      private static final long serialVersionUID = 1L;

      @Override
      protected void onUpdate(AjaxRequestTarget arg0) {
        arg0.addComponent(sdtChoices);

      }

    });

    sdtChoices.add(new AjaxFormComponentUpdatingBehavior("onchange") {
      /**
       * 
       */
      private static final long serialVersionUID = 1L;

      @Override
      protected void onUpdate(AjaxRequestTarget arg0) {
        arg0.addComponent(propertyChoices);

      }

    });

    propertyChoices.add(new AjaxFormComponentUpdatingBehavior("onchange") {
      @Override
      protected void onUpdate(AjaxRequestTarget arg0) {
        arg0.addComponent(valueChoices);

      }

    });

  }

  /**
   * Sets all the trigger options in page parameters.
   */
  @Override
  protected void onSubmit() {
    triggerModel.setType(selectedTriggerType);
    triggerModel.setSdt(selectedTriggerSdt);
    triggerModel.setProperty(selectedTriggerProperty);
    triggerModel.setValue(selectedTriggerValue);
    param.put(TYPE_TOKEN, triggerModel.getType());
    param.put(SDT_TOKEN, triggerModel.getSdt());
    param.put(PROPERTY_TOKEN, triggerModel.getProperty());
    param.put(VALUE_TOKEN, triggerModel.getValue());

    Trigger trigger = new Trigger();
    // trigger.setType(triggerModel.getTriggerType());
    if ("SensorData".equals(selectedTriggerType)) {
      trigger.setType(selectedTriggerType);
      trigger.setSDT(selectedTriggerSdt);
      trigger.setProperty(selectedTriggerProperty);
      trigger.setValue(selectedTriggerValue);
    }
    else if ("Coverage".equals(selectedTriggerType)) {
      trigger.setType(selectedTriggerType);
      trigger.setProperty(selectedTriggerProperty);
      // trigger.setMinValue());
    }

    // set response page to go to actions
    setResponsePage(SetActionPage.class, param);
  }

}
